﻿using System;
using System.Collections.Generic;
using DotNetNeural.Data.Base;

namespace DotNetNeural.Data.Learning
{
    public class TrainingSet : ITrainingSet
    {
        public TrainingSet(int inputsCount, int outputsCount)
        {
            if (inputsCount <= 0 || outputsCount <= 0)
                throw new ArgumentException("Illegal non-positive args");

            InputsCount = inputsCount;
            OutputsCount = outputsCount;

            learningItems = new List<TrainingSetItem>();
            controlItems = new List<TrainingSetItem>();
        }

        #region ITrainingSet Members

        public int InputsCount { get; private set; }

        public int OutputsCount { get; private set; }

        public void AddItem(TrainingSetItem item, bool isReserved)
        {
            if (item == null)
                return;

            if (item.Input.Length != InputsCount || item.Output.Length != OutputsCount)
                throw new ArgumentException("Illegal dimensions of item");

            if (isReserved)
                controlItems.Add(item);
            else
                learningItems.Add(item);
        }

        public void AddItems(IEnumerable<TrainingSetItem> items, bool isReserved)
        {
            if (items == null)
                return;

            foreach (var i in items)
            {
                AddItem(i, isReserved);
            }
        }

        public void AddItems(bool isReserved, params TrainingSetItem[] items)
        {
            AddItems(items, isReserved);
        }

        public IEnumerable<TrainingSetItem> ControlItems
        {
            get
            {
                return controlItems.AsReadOnly();
            }
        }

        public IEnumerable<TrainingSetItem> LearningItems
        {
            get
            {
                return learningItems.AsReadOnly();
            }
        }

        public Iterator<TrainingSetItem> CreateIterator(bool useControlItems)
        {
            return new TrainingSetIterator(this, useControlItems);
        }

        #endregion

        #region Private fields

        private List<TrainingSetItem> learningItems;
        private List<TrainingSetItem> controlItems;

        #endregion
    }
}
